<template>
    <div class="pa-2 playbar-main">
        <!-- 时间轴 -->
        <div class="row">
            <!-- 当前时间 -->
            <span class="px-1 time-label">
                {{ nowTime }}
            </span>

            <!-- 进度条 -->
            <div style="flex-grow: 1; width: 0; height: 31px">
                <v-slider
                    density="compact"
                    :model-value="isSlide ? percentageEmit : percentage"
                    @update:model-value="(v) => (percentageEmit = v)"
                    @start="startSlide"
                    @end="endSlide"
                    thumb-label
                >
                    <template v-slot:thumb-label>
                        {{ nowTime }}
                    </template>
                </v-slider>
            </div>

            <!-- 总时间 -->
            <span class="px-1 time-label" style="text-align: right">
                {{ maxTime }}
            </span>
        </div>

        <!-- 控制按钮 -->
        <div class="row row-end">
            <!-- 随机播放 -->
            <v-btn icon class="mx-2" color="primary" :elevation="2" size="small" @click="playlist.toggleShuffle">
                <v-icon>
                    {{ playlist.shuffle ? "mdi-shuffle-variant" : "mdi-shuffle-disabled" }}
                </v-icon>
                <v-tooltip activator="parent" location="top">
                    {{ playlist.shuffle ? "随机播放：开启" : "随机播放：取消" }}
                    {{
                        Shortcut.isAvailableState(shortcuts.toggleShuffle.shortcut)
                            ? `（${Shortcut.stateToString(shortcuts.toggleShuffle.shortcut)}）`
                            : ""
                    }}
                </v-tooltip>
            </v-btn>

            <!-- 上一首 -->
            <v-btn icon class="mx-2" color="primary" :elevation="2" size="small" @click="playlist.previous">
                <v-icon>mdi-skip-previous</v-icon>
                <v-tooltip activator="parent" location="top">
                    上一首{{
                        Shortcut.isAvailableState(shortcuts.previous.shortcut)
                            ? `（${Shortcut.stateToString(shortcuts.previous.shortcut)}）`
                            : ""
                    }}
                </v-tooltip>
            </v-btn>

            <!-- 播放暂停 -->
            <v-btn icon class="mx-2" color="primary" :elevation="4" @click="playlist.togglePause">
                <v-icon>
                    {{ playlist.player.state !== PlayState.Play ? "mdi-play" : "mdi-pause" }}
                </v-icon>
                <v-tooltip activator="parent" location="top">
                    {{ playlist.player.state !== PlayState.Play ? "播放" : "暂停" }}
                    {{
                        Shortcut.isAvailableState(shortcuts.togglePause.shortcut)
                            ? `（${Shortcut.stateToString(shortcuts.togglePause.shortcut)}）`
                            : ""
                    }}
                </v-tooltip>
            </v-btn>

            <!-- 下一首 -->
            <v-btn icon class="mx-2" color="primary" :elevation="2" size="small" @click="playlist.next">
                <v-icon>mdi-skip-next</v-icon>
                <v-tooltip activator="parent" location="top">
                    下一首{{
                        Shortcut.isAvailableState(shortcuts.next.shortcut)
                            ? `（${Shortcut.stateToString(shortcuts.next.shortcut)}）`
                            : ""
                    }}
                </v-tooltip>
            </v-btn>

            <!-- 播放模式 -->
            <v-btn icon class="mx-2" color="primary" :elevation="2" size="small" @click="changePlayMode">
                <v-icon>{{ modeIcon[0] }}</v-icon>
                <v-tooltip activator="parent" location="top">
                    {{ modeIcon[1] }}
                    {{
                        Shortcut.isAvailableState(shortcuts.switchMode.shortcut)
                            ? `（${Shortcut.stateToString(shortcuts.switchMode.shortcut)}）`
                            : ""
                    }}
                </v-tooltip>
            </v-btn>
        </div>
    </div>
</template>

<script setup lang="ts">
import { computed, ref, watch } from "vue";
import { Shortcut } from "@/lib/keyboard";
import { formatDuration } from "@/lib/utils";
import { Playlist, PlayMode, PlayState } from "@/lib/playlist";
import usePlaylistStore from "@/store/playlist";
import useShortcutStore from "@/store/shortcut";

const playlist = usePlaylistStore();
const shortcut = useShortcutStore();

// 播放进度百分比
const percentage = computed(() => {
    if (playlist.player.id === "") {
        return 0;
    }
    return (100 * playlist.duration) / playlist.player.duration;
});
const percentageEmit = ref(0);

// 是否正在滑动
const isSlide = ref(false);

// 当前播放时间 / Midi 总时长
let nowTimeSecs = 0;
const nowTime = ref(formatDuration(0));
const maxTime = ref(formatDuration(0));

// 注册快捷键
const shortcuts = {
    replay: shortcut.register("playbar-replay"),
    toggleShuffle: shortcut.register("playbar-toggle-shuffle"),
    previous: shortcut.register("playbar-previous"),
    togglePause: shortcut.register("playbar-toggle-pause"),
    next: shortcut.register("playbar-next"),
    switchMode: shortcut.register("playbar-switch-mode"),
};

// 设置快捷键信息
shortcuts.replay.description = "重新播放";
shortcuts.toggleShuffle.description = "随机播放";
shortcuts.previous.description = "上一首";
shortcuts.togglePause.description = "播放/暂停";
shortcuts.next.description = "下一首";
shortcuts.switchMode.description = "切换播放模式";

// 启用快捷键
shortcut.bind("playbar-replay", () => Playlist.Player.replay(playlist.playlist));
shortcut.bind("playbar-toggle-shuffle", () => playlist.toggleShuffle());
shortcut.bind("playbar-previous", () => playlist.previous());
shortcut.bind("playbar-toggle-pause", () => playlist.togglePause());
shortcut.bind("playbar-next", () => playlist.next());
shortcut.bind("playbar-switch-mode", () => changePlayMode());

// 开始滑动
function startSlide() {
    isSlide.value = true;
}

// 终止滑动
async function endSlide() {
    await Playlist.Player.jump(playlist.playlist, percentageEmit.value / 100);
    isSlide.value = false;
}

// 修改当前播放时间
watch(
    () => [isSlide.value, playlist.duration / 1000] as [boolean, number],
    ([isSlide, durationSecs]) => {
        let newTimeSecs: number;
        if (isSlide) {
            newTimeSecs = (playlist.player.duration * percentageEmit.value) / 100_000;
        } else {
            newTimeSecs = durationSecs;
        }

        if (Math.floor(newTimeSecs) !== Math.floor(nowTimeSecs)) {
            nowTime.value = formatDuration(newTimeSecs);
        }
        nowTimeSecs = newTimeSecs;
    },
);

// 修改 Midi 总时长
watch(
    () => playlist.player.duration / 1000,
    (duraitonSecs) => {
        maxTime.value = formatDuration(duraitonSecs);
    },
);

// 播放模式对应的图标
const modeIcon = computed<[string, string]>(() => {
    switch (playlist.getMode()) {
        case PlayMode.Once:
            return ["mdi-numeric-1", "单次播放"];
        case PlayMode.Single:
            return ["mdi-repeat-once", "单曲循环"];
        case PlayMode.Order:
            return ["mdi-shuffle-disabled", "顺序播放"];
        case PlayMode.Loop:
            return ["mdi-repeat", "循环播放"];
    }
});

// 切换播放模式
function changePlayMode() {
    switch (playlist.getMode()) {
        case PlayMode.Once:
            playlist.setMode(PlayMode.Single);
            break;
        case PlayMode.Single:
            playlist.setMode(PlayMode.Order);
            break;
        case PlayMode.Order:
            playlist.setMode(PlayMode.Loop);
            break;
        case PlayMode.Loop:
            playlist.setMode(PlayMode.Once);
            break;
    }
}
</script>

<style scoped lang="scss">
.playbar-main {
    display: flex;
    flex-direction: column;
    align-items: center;
    height: 100%;
    width: 100%;

    .row {
        display: flex;
        flex-direction: row;
        align-items: center;
        justify-content: center;
        width: 100%;
        height: auto;
    }

    .row-end {
        flex-grow: 1;
        height: 0;
    }

    .time-label {
        font-size: 13px;
        width: 60px;
        user-select: none;
    }
}
</style>
